import { _decorator } from "cc";
const { ccclass } = _decorator;

export interface IState {
  onEnter?: () => void;
  onUpdate?: (dt: number) => void;
  onExit?: () => void;
}

@ccclass("StateMachine")
export class StateMachine {
  private _states: Map<string, IState> = new Map();
  private _currentState: IState = null;
  private _currentStateName: string = "";
  private _id: string;

  constructor(id: string) {
    this._id = id;
  }

  public getId(): string {
    return this._id;
  }

  public registerState(stateName: string, state: IState): void {
    if (!this._states.has(stateName)) {
      this._states.set(stateName, state);
    }
  }

  public changeState(stateName: string): void {
    if (this._currentStateName === stateName) return;

    const newState = this._states.get(stateName);
    if (!newState) {
      console.warn(
        `State ${stateName} does not exist in StateMachine ${this._id}!`
      );
      return;
    }

    if (this._currentState?.onExit) {
      this._currentState.onExit();
    }

    this._currentState = newState;
    this._currentStateName = stateName;

    if (this._currentState?.onEnter) {
      this._currentState.onEnter();
    }
  }

  public update(dt: number): void {
    if (this._currentState?.onUpdate) {
      this._currentState.onUpdate(dt);
    }
  }

  public getCurrentStateName(): string {
    return this._currentStateName;
  }
}
